﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ERF;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace FirstPerson.Objects
{
    /// <summary>
    /// Represents a skull on fire.
    /// </summary>
    class FireSkull : ModelGameObject
    {
        private Particle3DSample.ParticleSystem particleSystem;
        private Random rand;
        private const float FIRE_ANIMATION_INTERVAL = 10;
        private const float LIGHT_ANIMATION_INTERVAL = 100;
        private float lightAnimationTimer = 0f;
        private float fireAnimationTimer = 0f;

        /// <summary>
        /// Creates a new instance of FireSkull.
        /// </summary>
        /// <param name="game"></param>
        public FireSkull(ERFGame game)
            : base(game)
        {
            base.ObjectModel = game.Content.Load<Model>("Models\\Skull\\skull");
            this.particleSystem = new Particle3DSample.ParticleSystem(game, game.Content, "ParticleData\\FireSettings");
            this.Children.Add(this.particleSystem);
            this.rand = new Random();
            this.SetEffect();
        }

        private void SetEffect()
        {
            for (int i = 0; i < this.ObjectModel.Meshes.Count; i++) 
            {
                for (int j = 0; j < this.ObjectModel.Meshes[i].MeshParts.Count; j++)
                {
                    BasicShaderEffect effect = new BasicShaderEffect(base.CurrentGame);

                    if (this.ObjectModel.Meshes[i].MeshParts[j].Effect is BasicEffect)
                    {
                        BasicEffect oldEffect = (BasicEffect)this.ObjectModel.Meshes[i].MeshParts[j].Effect;
                        effect.Alpha = 1f;
                        effect.DiffuseColor = Color.Blue.ToVector3();
                        effect.LightDirection = new Vector3(0, 1, 0.5f);
                        effect.AmbientColor = Color.White.ToVector3();
                        effect.AmbientIntensity = 0.01f;
                        effect.DiffuseIntensity = 1f;
                        effect.SpecularColor = Color.White.ToVector3();
                        effect.SpecularIntensity = 0.4f;
                        effect.SpecularPower = 8f;
                        effect.Texture = base.CurrentGame.Content.Load<Texture2D>("Textures\\skullTexture");
                        effect.EnableTexture = true;
                        effect.EnableLight = true;
                        effect.FogColor = Color.Black.ToVector4();
                        effect.FogStart = 19f;
                        effect.FogEnd = 21f;
                        effect.FogEnabled = true;
                    }
                    else
                    {
                        BasicShaderEffect oldEffect = (BasicShaderEffect)this.ObjectModel.Meshes[i].MeshParts[j].Effect;
                        effect.Alpha = 1f;
                        effect.DiffuseColor = Color.Blue.ToVector3();
                        effect.LightDirection = new Vector3(0, 1, 0.5f);
                        effect.AmbientColor = Color.White.ToVector3();
                        effect.AmbientIntensity = 0.01f;
                        effect.DiffuseIntensity = 1f;
                        effect.SpecularColor = Color.White.ToVector3();
                        effect.SpecularIntensity = 0.4f;
                        effect.SpecularPower = 8f;
                        effect.Texture = base.CurrentGame.Content.Load<Texture2D>("Textures\\skullTexture");
                        effect.EnableTexture = true;
                        effect.EnableLight = true;
                        effect.FogColor = Color.Black.ToVector4();
                        effect.FogStart = 19f;
                        effect.FogEnd = 21f;
                        effect.FogEnabled = true;
                    }


                    this.meshEffects[i][j] = effect;
                }
            }
        }

        /// <summary>
        /// Sets the direction of the light.
        /// </summary>
        /// <param name="dir">The direction of the light.</param>
        private void SetLightDirection(ref Vector3 dir)
        {
            for (int i = 0; i < this.ObjectModel.Meshes.Count; i++)
            {
                for (int j = 0; j < this.ObjectModel.Meshes[i].MeshParts.Count; j++)
                {
                    this.meshEffects[i][j].LightDirection = dir;
                }
            }
        }

        public override void Update(GameTime gameTime, ref Matrix world)
        {
            this.lightAnimationTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            this.fireAnimationTimer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            if (this.lightAnimationTimer >= LIGHT_ANIMATION_INTERVAL)
            {
                // Set a new random light direction.
                this.lightAnimationTimer -= LIGHT_ANIMATION_INTERVAL;
                Vector3 lightDirection = new Vector3(-1f - ((float)rand.NextDouble() * 0.2f), 0.5f + ((float)rand.NextDouble() * 0.2f), 0.5f - ((float)rand.NextDouble() * 0.2f));
                this.SetLightDirection(ref lightDirection);

            }

            if (this.fireAnimationTimer >= FIRE_ANIMATION_INTERVAL)
            {
                this.fireAnimationTimer -= FIRE_ANIMATION_INTERVAL;
                for (int i = 0; i < 10; i++)
                    this.particleSystem.AddParticle(this.position, new Vector3(0, 0, 0));
            }
            
            base.Update(gameTime, ref world);
        }

        public override void DrawSolid(GameTime gameTime)
        {
           base.CurrentGame.GraphicsDevice.RenderState.AlphaBlendEnable = false;
           base.DrawSolid(gameTime);
        }
    }
}
